﻿using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;

namespace WorseGame.Content
{
    public class 钓鱼限制(IMonitor 监视器, IModHelper 助手)
    {
        private readonly IMonitor 监视器 = 监视器;
        private readonly IModHelper 助手 = 助手;
        private readonly Dictionary<string, 水域数据> 水域列表 = [];
        private const int 最大钓鱼数量 = 15;
        private const int 恢复时间秒数 = 120;
        private bool 上次更新时在钓鱼 = false;

        public void Initialize()
        {
            助手.Events.GameLoop.UpdateTicked += 更新时触发;
            助手.Events.GameLoop.OneSecondUpdateTicked += 每秒更新时触发;
            助手.Events.GameLoop.DayStarted += 每日开始时;
        }

        private void 每日开始时(object? sender, DayStartedEventArgs e)
        {
            水域列表.Clear();
        }

        private void 更新时触发(object? sender, UpdateTickedEventArgs e)
        {
            if (Game1.player.CurrentTool is StardewValley.Tools.FishingRod 鱼竿)
            {
                bool 现在在钓鱼 = 鱼竿.isFishing;
                if (上次更新时在钓鱼 && !现在在钓鱼)
                {
                    处理钓到鱼();
                }
                上次更新时在钓鱼 = 现在在钓鱼;
                if (现在在钓鱼 && 是否水域恢复中())
                {
                    阻止钓鱼(鱼竿);
                }
            }
            else
            {
                上次更新时在钓鱼 = false;
            }
        }

        private void 每秒更新时触发(object? sender, OneSecondUpdateTickedEventArgs e)
        {
            更新恢复计时器();
        }

        private void 处理钓到鱼()
        {
            string 水域标识 = 获取当前水域标识();
            if (!水域列表.TryGetValue(水域标识, out 水域数据? 水域))
            {
                水域 = new 水域数据();
                水域列表[水域标识] = 水域;
            }

            水域.钓鱼数量++;
            if (水域.钓鱼数量 >= 最大钓鱼数量)
            {
                开始恢复(水域);
            }
        }

        private static void 开始恢复(水域数据 水域)
        {
            水域.是否恢复中 = true;
            水域.恢复计时器 = 恢复时间秒数;
            Game1.addHUDMessage(new HUDMessage("这个水域的鱼被钓光了，需要时间恢复", 2));
        }

        private void 更新恢复计时器()
        {
            foreach (var 水域项 in 水域列表)
            {
                var 水域 = 水域项.Value;

                if (水域.是否恢复中 && 水域.恢复计时器 > 0)
                {
                    水域.恢复计时器--;
                    if (水域.恢复计时器 <= 0)
                    {
                        水域.是否恢复中 = false;
                        水域.钓鱼数量 = 0;
                        Game1.addHUDMessage(new HUDMessage("水域恢复完成，可以继续钓鱼了", 1));
                    }
                }
            }
        }

        private static void 阻止钓鱼(StardewValley.Tools.FishingRod 鱼竿)
        {
            鱼竿.isFishing = false;
            鱼竿.castingChosenCountdown = 0;
            鱼竿.doneFishing(Game1.player, true);
            Game1.showRedMessage("这个水域正在恢复中，无法钓鱼！");
            Game1.playSound("cancel");
        }

        public bool 是否水域恢复中()
        {
            string 水域标识 = 获取当前水域标识();
            return 水域列表.ContainsKey(水域标识) && 水域列表[水域标识].是否恢复中;
        }

        private static string 获取当前水域标识()
        {
            var 当前位置 = Game1.currentLocation;
            int 区域X = (int)(Game1.player.Position.X / 256);
            int 区域Y = (int)(Game1.player.Position.Y / 256);

            return $"{当前位置.Name}_{区域X}_{区域Y}";
        }

        public int 获取剩余恢复时间()
        {
            string 水域标识 = 获取当前水域标识();
            if (水域列表.TryGetValue(水域标识, out 水域数据? 水域))
            {
                return 水域.恢复计时器;
            }
            return 0;
        }

        private class 水域数据
        {
            public int 钓鱼数量 { get; set; }
            public bool 是否恢复中 { get; set; }
            public int 恢复计时器 { get; set; }
        }
    }
}